home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / misc / CapiRexxVoiceM.lha / arexx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-07  |  9.0 KB  |  502 lines

  1. /*
  2. **
  3. **    $Id: arexx.c,v 1.1 1995/10/07 02:48:56 amiga Exp $
  4. **    $Revision: 1.1 $
  5. **
  6. **    $Filename: answeringmachine/arexx.c $
  7. **    $Author: amiga $
  8. **    $Date: 1995/10/07 02:48:56 $
  9. **    $Portability: AMIGADOS $
  10. **
  11. **    ARexx interface
  12. **
  13. **    COPYRIGHT (C) 1991, 1992 BY CHRISTIAN A. WEBER, ZUERICH.
  14. **    COPYRIGHT (C) 1992-1995 BY RELOG AG, ZUERICH. ALL RIGHTS RESERVED.
  15. **    NO PART OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, OR TRANSMITTED
  16. **    IN ANY FORM OR BY ANY MEANS,  WITHOUT THE PRIOR WRITTEN PERMISSION
  17. **    OF RELOG AG.
  18. **
  19. */
  20.  
  21. #include "os.h"
  22.  
  23. #include <proto/exec.h>
  24. #include <clib/rexxsyslib_protos.h>
  25. #include <pragmas/rexxsyslib_pragmas.h>
  26. #include <proto/dos.h>
  27. #include <proto/intuition.h>
  28. #include <proto/utility.h>
  29.  
  30. #include <string.h>
  31. #include <stdio.h>
  32.  
  33. #define  _AREXX
  34. #include "arexx.h"
  35.  
  36. #include "am.h"
  37.  
  38. #define MYREXXSUFFIX    "amrx"
  39.  
  40.  
  41. static struct Library        *RexxSysBase;
  42.  
  43.  
  44. /****************************************************************************
  45. **    ASCII String holen, Anführungszeichen interpretieren.
  46. **    Der Char*-Zeiger wird auf den Text nach dem String gesetzt.
  47. **    Gibt FALSE zurück, wenn kein Argument mehr vorhanden ist.
  48. */
  49.  
  50. BOOL ARexx_GetString( char **strptr, char *dest, int destsize )
  51. {
  52.     char    *s = *strptr;
  53.     BOOL    result = FALSE;
  54.  
  55.     /*
  56.     **    Führende Spaces überlesen
  57.     */
  58.     while (*s == ' ')
  59.         s++;
  60.  
  61.  
  62.     /*
  63.     **    Text kopieren
  64.     */
  65.     if (*s == '"')        /* Anführungszeichen --> plain copy */
  66.     {
  67.         s++;
  68.         while (*s != '\0')
  69.         {
  70.             result = TRUE;
  71.             if (*s == '\\')        /* Escape-Sequenz */
  72.             {
  73.                 s++;
  74.                 if (*s == '\0')
  75.                     break;
  76.  
  77.                 switch (*s)
  78.                 {
  79.                     case 'n':
  80.                         if (destsize > 0)
  81.                         {
  82.                             *dest++ = '\n';
  83.                             destsize--;
  84.                         }
  85.                         break;
  86.  
  87.                     default:
  88.                         if (destsize > 0)
  89.                         {
  90.                             *dest++ = *s;
  91.                             destsize--;
  92.                         }
  93.                         break;
  94.                 }
  95.                 s++;
  96.             }
  97.             else if (*s == '"')
  98.             {
  99.                 s++;
  100.                 break;
  101.             }
  102.              else
  103.              {
  104.                  if (destsize > 0)
  105.                  {
  106.                     *dest++ = *s;
  107.                     destsize--;
  108.                 }
  109.                 s++;
  110.             }
  111.         }
  112.     }
  113.     else                /* Keine Anführungszeichen --> bis Space */
  114.     {
  115.         while (*s != '\0')
  116.         {
  117.             result = TRUE;
  118.             if (*s == '\\')        /* Escape-Sequenz */
  119.             {
  120.                 s++;
  121.                 if (*s == '\0')
  122.                     break;
  123.  
  124.                 switch (*s)
  125.                 {
  126.                     case 'n':
  127.                         if (destsize > 0)
  128.                         {
  129.                             *dest++ = '\n';
  130.                             destsize--;
  131.                         }
  132.                         break;
  133.  
  134.                     default:
  135.                         if (destsize > 0)
  136.                         {
  137.                             *dest++ = *s;
  138.                             destsize--;
  139.                         }
  140.                         break;
  141.                 }
  142.                 s++;
  143.             }
  144.             else if(*s == ' ')
  145.             {
  146.                 break;
  147.             }
  148.              else
  149.              {
  150.                  if (destsize > 0)
  151.                  {
  152.                     *dest++ = *s;
  153.                     destsize--;
  154.                 }
  155.                 s++;
  156.             }
  157.         }
  158.     }
  159.     *dest = '\0';
  160.  
  161.     /*
  162.     **    Spaces am Schluss überlesen
  163.     */
  164.     while (*s == ' ')
  165.         s++;
  166.  
  167.     *strptr = s;
  168.  
  169.     return result;
  170. }
  171.  
  172.  
  173. /****************************************************************************
  174. **    ASCII nach Integer wandeln, Nachkommastellen werden unterdrückt.
  175. **    Der Char*-Zeiger wird auf den Text nach der Zahl gesetzt.
  176. **    Gibt FALSE zurück, wenn keine Zahl erkannt wurde.
  177. */
  178.  
  179. BOOL ARexx_GetInteger( char **strptr, S32 *pInt )
  180. {
  181.     char    *s = *strptr;
  182.     S32        zahl = 0;
  183.     S8        sign = 1;
  184.     BOOL    result = FALSE;
  185.  
  186.     while (*s == ' ')
  187.         s++;
  188.  
  189.     if (*s == '-')
  190.     {
  191.         sign = -1;
  192.         s++;
  193.     }
  194.     else if(*s == '+')
  195.         s++;
  196.  
  197.     while ((*s >= '0') && (*s <= '9'))
  198.     {
  199.         zahl = zahl * 10 + (*s++ - '0');
  200.         result = TRUE;
  201.     }
  202.  
  203.     while (*s == ' ')
  204.         s++;
  205.  
  206.     *strptr = s;
  207.     *pInt = (sign > 0) ? zahl : -zahl;
  208.  
  209.     return result;
  210. }
  211.  
  212.  
  213. /****************************************************************************
  214. **    Ein Rexx-Kommando auswerten, geht auch wenn ARexx NICHT läuft
  215. */
  216.  
  217. static S32 PerformRexxCommand( char *commandline, struct AnsweringMachine *am )
  218. {
  219.     static struct MyRexxCmd
  220.     {
  221.         char    *Name;
  222.         S32        (*Func)( char *, struct AnsweringMachine * );
  223.     }
  224.     rexxcmdtab[] =
  225.     {
  226.         "BACKGROUND",            RXFunc_Background,
  227.         "FADE",                    RXFunc_Fade,
  228.         "HANGUP",                RXFunc_HangUp,
  229.         "PLAY",                    RXFunc_Play,
  230.         "RECORD",                RXFunc_Record,
  231.         "WAITKEY",                RXFunc_WaitKey,
  232.         NULL,                    NULL
  233.     };
  234.  
  235.     struct MyRexxCmd *cptr;
  236.  
  237.     printf( "PerformRexxCommand( \"%s\" )\n", commandline );
  238.  
  239.     rexx_resultstring[0] = '\0';        /* Resultat löschen */
  240.  
  241.     for (cptr = rexxcmdtab; cptr->Name; cptr++)
  242.     {
  243.         char *s, *d;
  244.         for (s = commandline, d=cptr->Name; *d; s++, d++)
  245.         {
  246.             if(ToUpper( (ULONG)*s ) != *d )
  247.                 break;
  248.         }
  249.  
  250.         if (*s <= ' ')                            /* Kommandoname fertig: das richtige */
  251.         {
  252.             S32 result;
  253.  
  254.             while (*s == ' ')                    /* Spaces überhüpfen */
  255.                 s++;
  256.  
  257.             /* arexxflag = TRUE; */
  258.             result = (*cptr->Func)( s, am );    /* Funktion aufrufen */
  259.             /* arexxflag = FALSE; */
  260.  
  261.             return result;
  262.         }
  263.     }
  264.  
  265.     printf( "Unknown command!\n" );
  266.     return RC_ERROR;
  267. }
  268.  
  269.  
  270. /****** ARexx_Init **********************************************************
  271. *
  272. *   NAME
  273. *       ARexx_Init -- Initialize ARexx
  274. *
  275. *   SYNOPSIS
  276. *       sigmask = ARexx_Init()
  277. *
  278. *       BOOL ARexx_Init( VOID );
  279. *
  280. *   FUNCTION
  281. *       Opens the required libraries (rexxsyslib)
  282. *
  283. *   INPUTS
  284. *
  285. *   RESULTS
  286. *
  287. *   SEE ALSO
  288. *       ARexx_Exit()
  289. *
  290. ****************************************************************************/
  291.  
  292. BOOL ARexx_Init( VOID )
  293. {
  294.     if (RexxSysBase = OpenLibrary( RXSNAME, 0 ))
  295.     {
  296.         return TRUE;
  297.     }
  298.  
  299.     ARexx_Exit();
  300.     return 0;
  301. }
  302.  
  303.  
  304. /****** ARexx_Exit **********************************************************
  305. *
  306. *   NAME
  307. *       ARexx_Exit -- Close our ARexx port
  308. *
  309. *   SYNOPSIS
  310. *       ARexx_Exit()
  311. *
  312. *       VOID ARexx_Exit( VOID );
  313. *
  314. *   FUNCTION
  315. *       Tries to close down our ARexx port and all associated resources.
  316. *       Will wait until all running scripts have terminated.
  317. *
  318. *   INPUTS
  319. *
  320. *   RESULTS
  321. *
  322. *   SEE ALSO
  323. *       ARexx_Init()
  324. *
  325. ****************************************************************************/
  326.  
  327. VOID ARexx_Exit( VOID )
  328. {
  329.     if (RexxSysBase != NULL)
  330.     {
  331.         CloseLibrary( RexxSysBase );
  332.         RexxSysBase = NULL;
  333.     }
  334. }
  335.  
  336.  
  337. /****** ARexx_HandleMessages ************************************************
  338. *
  339. *   NAME
  340. *       ARexx_HandleMessages -- Handle ARexx messages
  341. *
  342. *   SYNOPSIS
  343. *       ARexx_HandleMessages( port, userdata )
  344. *
  345. *       VOID ARexx_HandleMessages( struct MsgPort *, VOID * );
  346. *
  347. *   FUNCTION
  348. *       Handles all ARexx messages which are currently waiting on our
  349. *       message port. This function is usually called after the ARexx
  350. *       signal has been received.
  351. *
  352. *   INPUTS
  353. *       port     - Port to get messages from
  354. *       userdata - User data, will be forwarded to all functions
  355. *
  356. *   RESULTS
  357. *       none
  358. *
  359. *   SEE ALSO
  360. *
  361. ****************************************************************************/
  362.  
  363. VOID ARexx_HandleMessages( struct ARexxPort *ap )
  364. {
  365.     struct RexxMsg *msg;
  366.  
  367.     /* printf( "ARexx_HandleMessages( 0x%08lx )\n", ap ); */
  368.  
  369.     if (ap == NULL)        /* Sofort zurück falls ARexx nicht läuft */
  370.         return;
  371.  
  372.     while (msg = (struct RexxMsg *)GetMsg( ap->Port ))
  373.     {
  374.         if (msg->rm_Node.mn_Node.ln_Type != NT_REPLYMSG)
  375.         {
  376.             /*
  377.             **    Es ist eine gültige Message und nicht eine Antwort.
  378.             */
  379.             if (IsRexxMsg( msg ))
  380.             {
  381.                 /* Sollen wir ein Kommando auführen ? */
  382.                 if ((msg->rm_Action & RXCODEMASK) == RXCOMM)
  383.                 {
  384.                     msg->rm_Result1 = 0;
  385.                     msg->rm_Result2 = 0;
  386.  
  387.                     if (msg->rm_Result1 = PerformRexxCommand( msg->rm_Args[0], ap->UserData ))
  388.                     {
  389.                         /* Func returned an error */
  390.                     }
  391.                     else if((*rexx_resultstring)    && (msg->rm_Action & RXFF_RESULT))
  392.                     {
  393.                         msg->rm_Result2 = (LONG)
  394.                             CreateArgstring( rexx_resultstring, (ULONG)strlen( rexx_resultstring ) );
  395.                     }
  396.                 }
  397.             }
  398.  
  399.             ReplyMsg( &msg->rm_Node );
  400.         }
  401.         else
  402.         {
  403.             /*
  404.             **    Diese Message ist ein reply auf eine Message welche wir
  405.             **    früher mal geschickt haben
  406.             */
  407.             DeleteArgstring( msg->rm_Args[0] );
  408. #if 0
  409.             if (msg->rm_Stdin)
  410.                 Close( msg->rm_Stdin );
  411. #endif
  412.             DeleteRexxMsg( msg );
  413.             ap->MsgCount--;
  414.         }
  415.     }
  416. }
  417.  
  418.  
  419. /****************************************************************************
  420. **    Eine RexxMessage schicken (Speicher wird von RexxMsgHandler freigegeben)
  421. **    Parameter: Kommando-String
  422. */
  423.  
  424. BOOL
  425. ARexx_LaunchScript( struct ARexxPort *ap, char *command )
  426. {
  427.     struct MsgPort *masterport;
  428.  
  429.     if (masterport = FindPort( "REXX" ))
  430.     {
  431.         struct RexxMsg *msg;
  432.  
  433.         if (msg = CreateRexxMsg( ap->Port, MYREXXSUFFIX, ap->Port->mp_Node.ln_Name ))
  434.         {
  435.             if(msg->rm_Args[0] = CreateArgstring( command, (ULONG)strlen( command ) ))
  436.             {
  437.                 msg->rm_Action    = RXCOMM | RXFF_TOKEN;
  438.                 msg->rm_Stdin    = Input();
  439.                 msg->rm_Stdout    = Output();
  440.                 PutMsg( masterport, &msg->rm_Node );
  441.                 ap->MsgCount++;
  442.  
  443.                 return  TRUE;
  444.             }
  445.  
  446.             printf( "ARexx_LaunchScript(): CreateArgString failed\n" );
  447.             DeleteRexxMsg( msg );
  448.         }
  449.  
  450.         printf( "ARexx_LaunchScript(): CreateRexxMsg failed\n" );
  451.     }
  452.  
  453.     printf( "ARexx_LaunchScript(): Can't find REXX port\n" );
  454.  
  455.     return FALSE;
  456. }
  457.  
  458.  
  459. /*
  460. **    ARexx-Port erzeugen
  461. */
  462. struct ARexxPort *ARexx_CreatePort( char *name, VOID *userdata )
  463. {
  464.     struct ARexxPort *ap;
  465.  
  466.     if (ap = (struct ARexxPort *)OS_Malloc( sizeof( *ap ) ))
  467.     {
  468.         if (ap->Port = CreatePort( name, 0 ))
  469.         {
  470.             ap->UserData = userdata;
  471. /*            ap->UseCount = 0; */
  472.         }
  473.         else
  474.         {
  475.             OS_Free( ap );
  476.             ap = NULL;
  477.         }
  478.     }
  479.  
  480.     return ap;
  481. }
  482.  
  483.  
  484. /*
  485. **    ARexx-Port freigeben
  486. */
  487. VOID ARexx_DeletePort( struct ARexxPort *ap )
  488. {
  489.     if (ap != NULL)
  490.     {
  491.         if (ap->MsgCount > 0)
  492.         {
  493.             printf( "Port %s: UseCount = %ld, waiting ...\n", ap->Port->mp_Node.ln_Name, ap->MsgCount );
  494.             ARexx_HandleMessages( ap );
  495.             WaitPort( ap->Port );
  496.         }
  497.  
  498.         DeletePort( ap->Port );
  499.         OS_Free( ap );
  500.     }
  501. }
  502.